/**
 *  This file is part of TaoBaoItemImporter.
 *
 *   TaoBaoItemImporter is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   TaoBaoItemImporter is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with TaoBaoItemImporter.  If not, see <http://www.gnu.org/licenses/>. 
 */
package com.googlecode.ulysses.taobao.synchronization;

import java.net.*;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.GnuParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.OptionBuilder;
import org.apache.commons.cli.Options;

import com.mongodb.*;
import com.googlecode.ulysses.taobao.Connector;
import com.googlecode.ulysses.taobao.Constants;
import com.googlecode.ulysses.taobao.importer.Workman;

import com.googlecode.ulysses.taobao.*; 
/**
 * 
 * @author Hegen <lhegen@gmail.com>
 *
 */
/*
 * Usage: 
 * You need two collections to run this application, one source collection
 * such as items collection, another destination collection such as tj_cats_p, tj_cats_s
 */
public class DBSynchronization {
	@SuppressWarnings("static-access")
	public static void main(String[] args) throws UnknownHostException, MongoException{
		/* Get arguments */
		//Source database information
		String shost = Constants.DEFAULT_MONGO_HOST;
		int sport = Constants.DEFAULT_MONGO_PORT;
		String suser = "";
		String ssecurity = "";
		String sdb = "";
		String scoll = "";
		
		//Destination database information
		String dhost = Constants.DEFAULT_MONGO_HOST;
		int dport = Constants.DEFAULT_MONGO_PORT;
		String duser = "";
		String dsecurity = "";
		String ddb = "";
		String dcoll = "";


		Options options = new Options();

		options.addOption(OptionBuilder.isRequired(false).hasArg()
				.withDescription("[Optional] Source mongodb host, default localhost")
				.withLongOpt("src host").create("sh"));
		options.addOption(OptionBuilder
				.isRequired(false)
				.hasArg()
				.withDescription(
						"[Optional] Source mongodb port number, default 27017")
				.withLongOpt("src port").create("sp"));
		options.addOption(OptionBuilder
				.isRequired(false)
				.hasArg()
				.withDescription(
						"[Optional] Source mongodb login user, such as tester")
				.withLongOpt("src user").create("su"));
		options.addOption(OptionBuilder.isRequired(false).hasArg()
				.withDescription("[Optional] Source mongodb login password")
				.withLongOpt("src password").create("ss"));
		options.addOption(OptionBuilder.isRequired().hasArg()
				.withDescription("Source mongodb database name")
				.withLongOpt("src database").create("sd"));
		options.addOption(OptionBuilder.isRequired().hasArg()
				.withDescription("Source mongodb collection name")
				.withLongOpt("src collection").create("sc"));
		
		options.addOption(OptionBuilder.isRequired(false).hasArg()
				.withDescription("[Optional] Destination mongodb host, default localhost")
				.withLongOpt("dst host").create("dh"));
		options.addOption(OptionBuilder
				.isRequired(false)
				.hasArg()
				.withDescription(
						"[Optional] Destination mongodb port number, default 27017")
				.withLongOpt("dst port").create("dp"));
		options.addOption(OptionBuilder
				.isRequired(false)
				.hasArg()
				.withDescription(
						"[Optional] Destination mongodb login user, such as tester")
				.withLongOpt("dst user").create("du"));
		options.addOption(OptionBuilder.isRequired(false).hasArg()
				.withDescription("[Optional] Destination mongodb login password")
				.withLongOpt("dst password").create("ds"));
		options.addOption(OptionBuilder.isRequired().hasArg()
				.withDescription("Destination mongodb database name")
				.withLongOpt("dst database").create("dd"));
		options.addOption(OptionBuilder.isRequired().hasArg()
				.withDescription("Destination mongodb collection name")
				.withLongOpt("dst collection").create("dc"));

		CommandLineParser parser = new GnuParser();
		try {
			CommandLine line = parser.parse(options, args);
			shost = line.getOptionValue("src host");
			sport = line.getOptionValue("src port") == null ? Constants.DEFAULT_MONGO_PORT
					: Integer.parseInt(line.getOptionValue("src port"));
			suser = line.getOptionValue("src user");
			ssecurity = line.getOptionValue("src password");
			sdb = line.getOptionValue("src database");
			scoll = line.getOptionValue("src collection");
			
			dhost = line.getOptionValue("dst host");
			dport = line.getOptionValue("dst port ") == null ? Constants.DEFAULT_MONGO_PORT
					: Integer.parseInt(line.getOptionValue("dst port"));
			duser = line.getOptionValue("dst user");
			dsecurity = line.getOptionValue("dst password");
			ddb = line.getOptionValue("dst database");
			dcoll = line.getOptionValue("dst collection");
			
		} catch (org.apache.commons.cli.ParseException e) {
			System.err.print("Parsing failed.  Reason: " + e.getMessage());
			System.err.println();
			// automatically generate the help statement
			HelpFormatter formatter = new HelpFormatter();
			Workman workman = new Workman();
			formatter.printHelp(workman.getClass().getCanonicalName(), options);
			return;
		}

		//Source and destination database connctions
		Connector srcconn = null;
		Connector dstconn = null;
		if (suser != null && ssecurity != null)
			srcconn = new Connector(shost, sport, suser, ssecurity.toCharArray());
		else
			srcconn = new Connector(shost, sport);

		if (duser != null && dsecurity != null)
			dstconn = new Connector(dhost, dport, duser, dsecurity.toCharArray());
		else
			dstconn = new Connector(dhost, dport);

		
		/* Get the collection handler */
		srcconn.connect();
		DBCollection srccollObj = srcconn.getCollectionObj(sdb, scoll);

		dstconn.connect();
		DBCollection dstcollObj = dstconn.getCollectionObj(ddb, dcoll);
		
		BackDBWriter writer = null;
		if (dcoll.equals("tj_cats_p")){
			writer = new CategoryWriter(srccollObj, dstcollObj);
		}
		else if (dcoll.equals("tj_cats_s")){
			writer = new SubCategoryWriter(srccollObj, dstcollObj);
		}
		else if(dcoll.equals("tj_items")){
			writer = new TjItemWriter(srccollObj, dstcollObj);
		}
		
		writer.writeCategoryDB();
	}
}
